//---------------Sonic CD Special Setup Script----------------//
//--------Scripted by Christian Whitehead 'The Taxman'--------//
//-------Unpacked By Rubberduckycooly's Script Unpacker-------//

// Aliases

// Universal
private alias object.value5 : Object.ScreenDepth

// HUD Alias
private alias object.value0 : HUD.UFOsCount
private alias object.value1 : HUD.TimeSeconds
private alias object.value2 : HUD.TimeFrames
private alias object.value6 : HUD.BonusUFONo // "No" akin to Entity No, not as in "is there no UFO?"
private alias object.value7 : HUD.WaterTimer

// UFO Alias
private alias object.ypos : Object.ZPos

// SSSonic Aliases
// WARNING: Variable VAR_PLAYERCONTROLMODE does not exist in RSDKv4!
private alias object[0].controlMode : SSSonic.ControlMode

// ControlMode Aliases
private alias -1 : CONTROLMODE_NONE

// Stage Finish State Aliases
private alias 9 : STAGEFINISH_LOADLEVELSELECT

// Game Mode Aliases
private alias 1 : MODE_TIMEATTACK

// Stage SFX
private alias 5 : SFX_S_TIMEUFO
private alias 7 : SFX_S_DROWNALERT

// Soundtrack
private alias 0 : OST_JP

// Priority
private alias 1 : PRIORITY_ACTIVE

// Tile Layer Types
private alias 3 : LAYER_3DFLOOR
private alias 4 : LAYER_3DSKY


event ObjectMain
	scene3D.vertexCount = 0
	scene3D.faceCount = 0

	// Update the oscillation value
	// Although it's normally used for synced movements throughout a stage, the Oscillation value is never actually used within the Special Stage
	Oscillation++
	if Oscillation == 512
		Oscillation = 0
	end if

	// Time is managed here

	if HUD.UFOsCount[4] > 0

		// This used to be checking if it was false, but Origins changed it up a bit
		if stage.timeEnabled == true
			// However, this is a bit faulty and results on a time ufo sometimes appearing in time attack, so let's exclude any of this from time attack for decomp
#platform: Use_Decomp
			if Options.GameMode != MODE_TIMEATTACK
#endplatform
				// Progress the timer
				HUD.TimeFrames[4]++
				if HUD.TimeFrames[4] == 60
					HUD.TimeFrames[4] = 0

					if HUD.TimeSeconds[4] > 0
						if HUD.TimeSeconds[4] < 6
							// Time's almost up, play a jingle to alert the player
// WARNING: Function FUNC_PLAYSTAGESFX does not exist in RSDKv4!
// Arguments: SFX_S_DROWNALERT, false
						PlaySFX(SFXName[Warning], 0)
						end if

						HUD.TimeSeconds[4]--
						if HUD.TimeSeconds[4] < 20
							// Less than 20 seconds left, quickly, spawn a time UFO to help the player!
							arrayPos0 = HUD.BonusUFONo[4]

							// Make sure the bonus UFO doesn't exist already
							if object[arrayPos0].type != TypeName[UFO]
// WARNING: Function FUNC_PLAYSTAGESFX does not exist in RSDKv4!
// Arguments: SFX_S_TIMEUFO, false
						PlaySFX(SFXName[TimeUFO], 0)


								arrayPos1 = arrayPos0
								arrayPos1++

								object[arrayPos0].type = TypeName[UFO]
								object[arrayPos0].priority = PRIORITY_ACTIVE
								object[arrayPos0].propertyValue = 2
								object[arrayPos0].xpos = object[arrayPos1].xpos
								Object.ZPos[arrayPos0] = Object.ZPos[arrayPos1]
							end if
						end if
					else
						// This will never happen on Time Attack
						if Options.GameMode != MODE_TIMEATTACK
							// Time's over, so start the stage results
							object[30].type = TypeName[Stage Finish]
							if stage.actNum == 8
								// If in the Robotnik Special Stage, then go to the Level Select
								object[30].state = STAGEFINISH_LOADLEVELSELECT
								object[30].drawOrder = 7
							else
								// Nope, we can just do normal results
								object[30].drawOrder = 6
							end if
							SSSonic.ControlMode = CONTROLMODE_NONE
						end if
					end if
				end if

				if HUD.WaterTimer[4] > 0
					if HUD.WaterTimer[4] > 1
						if HUD.WaterTimer[4] > 20
							temp0 = HUD.TimeFrames[4]
							temp0 &= 1

							if HUD.TimeSeconds[4] > 0
								HUD.TimeSeconds[4] -= temp0
							else
								// In Time Attack, you can't run out of time
								if Options.GameMode != MODE_TIMEATTACK
									// No more time left, end the stage by spawning the results
									object[30].type = TypeName[Stage Finish]

									if stage.actNum == 8
										// If in the Robotnik Special Stage, then go back to the Level Select rather than the normal SS results

										object[30].state = STAGEFINISH_LOADLEVELSELECT
										object[30].drawOrder = 7
									else
										// We're in a normal stage, so show the results as normal

										object[30].drawOrder = 6
									end if

									SSSonic.ControlMode = CONTROLMODE_NONE
								end if
							end if
						else
							if object[3].type != TypeName[WaterSplash]
								HUD.WaterTimer[4] = 0
							end if
						end if

						HUD.WaterTimer[4]--
					else
						if object[3].type != TypeName[WaterSplash]
							HUD.WaterTimer[4] = 0
						else
							temp0 = HUD.TimeFrames[4]
							temp0 &= 1

							if HUD.TimeSeconds[4] > 0
								HUD.TimeSeconds[4] -= temp0
							else

								// In Time Attack, you can't muddle your time up and time out
								if Options.GameMode != MODE_TIMEATTACK

									// Player wasted too much time puddling around and now time's up, end the stage
									object[30].type = TypeName[Stage Finish]

									if stage.actNum == 8

										// If we're in Robotnik's secret Special Stage, then return to the level select

										object[30].state = STAGEFINISH_LOADLEVELSELECT
										object[30].drawOrder = 7

									else

										// We're in a normal stage, so show the normal results

										object[30].drawOrder = 6

									end if

									SSSonic.ControlMode = CONTROLMODE_NONE
								end if

							end if
						end if
					end if
				end if
#platform: Use_Decomp
			end if
#endplatform
		end if
	end if

end event


event ObjectDraw
	// Sort the drawing orders of all entities
	// (Things further away from the camera should be drawn first and things closest should be last, etc.)

	temp0 = 0
	temp1 = screen.drawListSize[3]
	while temp0 < temp1
		temp2 = temp1
		temp2--

		while temp2 > temp0
			temp3 = temp2
			temp2--

			// Get the object slots of the two objects
			GetDrawListEntityRef(arrayPos0, 3, temp3)
			GetDrawListEntityRef(arrayPos1, 3, temp2)

			// Compare their sorted draw orders
			if Object.ScreenDepth[arrayPos0] > Object.ScreenDepth[arrayPos1]
				// Swap them around if needed
				SetDrawListEntityRef(arrayPos0, 3, temp2)
				SetDrawListEntityRef(arrayPos1, 3, temp3)
			end if
		loop

		temp0++
	loop

end event


event ObjectStartup

	// Despite not having any SpriteFrames to draw with, go ahead and load the Special Stage objects sheet anyways
	// (It doesn't make much of a difference but hey, may as well anyways!)
	LoadSpriteSheet("Special/Objects.gif")

	// Set the ground to the "3d Sky" layer type
	// -> This way, it'll render in high-quality mode if possible, as opposed to the "3d Floor" type
	tileLayer[0].type = LAYER_3DFLOOR

	SetMusicTrack("TEST.ogg", 0, true)
	SetMusicTrack("ActClear.ogg", 1, false)

	stage.pauseEnabled = false

	// Origins changed this up a bit - before, Time would always be disabled, but Origins makes it enabled for standard play
	if Options.GameMode == MODE_TIMEATTACK
		stage.timeEnabled = false
	else
		stage.timeEnabled = true
	end if

	object[23].type = TypeName[Special Setup]
	object[23].priority = PRIORITY_ACTIVE

	// Give it a draw order lower right before the primary one, to make sure it can sort all the upcoming 3d entities correctly
	object[23].drawOrder = 2

	// Cycle through all Blank Objects?
	// There was likely a proper name here in the original source,
	// but it was an invalid name so upon compiling, it got resolved as 0
	// What this original name was though, we have no idea...
	arrayPos0 = 32
	while arrayPos0 < 1056
		if object[arrayPos0].type == TypeName[Blank Object]
			// If the object is blank... then blank it again...
			ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
		end if

		arrayPos0++
	loop

end event


// ========================
// Editor Subs
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Display.gif")
	SpriteFrame(-16, -16, 32, 32, 1, 143) // "Script" Box


end event
